// @algorithm @lc id=1000254 lang=typescript
// @title XltzEq
// @test("A man, a plan, a canal: Panama")=true
function isPalindrome(s: string): boolean {
  const n = s.length;
  let l = 0;
  let r = n - 1;
  // 判断字符合法性
  const isValidaChars = (c: string) => {
    if (c >= 'a' && c <= 'z') return true;
    if (c >= 'A' && c <= 'Z') return true;
    if (c >= '0' && c <= '9') return true;
    return false;
  };
  while (l < r) {
    // 跳过非法字符
    while (l < n && !isValidaChars(s[l])) l++;
    while (r >= 0 && !isValidaChars(s[r])) r--;
    // 都是非法字符
    if (l === n || r === 0) return true;
    // 比较首尾字符
    if (s[l].toLocaleLowerCase() !== s[r].toLocaleLowerCase()) return false;
    l++, r--;
  }

  return true;
}
